package cn.com.pansky.service;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import cn.com.pansky.payment.PayConf;
import cn.com.pansky.util.AppUtils;
import cn.com.pansky.util.DateUtil;
import cn.com.pansky.util.HttpClientUtil;
import cn.com.pansky.util.PayUtils;

public class JHQuery {

	// 查询地址
	private String url;
	// 消息版本号 ( 1.0.0)
	private String version = PayConf.QUE_VERSION;
	// 字符编码(必填): GBK或UTF-8
	private String charset = PayConf.CHARSET;
	// 签名方法(必填): MD5
	private String signMethod = PayConf.SIGNMETHOD;
	// 支付接口类型 个人支付：B2C 企业支付：B2B
	private String payType = "";
	// 交易类型(必填): 01—消费交易查询
	private String transType = "01";
	// 商户编号(必填): 与清算平台签约时，由清算平台统一分配。最长30位
	private String merId = PayConf.MERID;
	// 商户密钥
	private String signKey = PayConf.SIGNKEY;
	// 商户订单号(可选，商户的交易定单号,由商户网站生成,最大长度32)
	private String orderNumber;
	// 交易时间 查询交易的交易开始日期时间(可选，格式：yyyyMMddHHmmss。)
	private String orderTime;
	// 原始交易流水号(可选)
	private String qid;
	
	public JHQuery() {
		
	}
	public JHQuery(String queryurl, String merId, String signKey, String orderNumber, String orderTime, String qid) {
		this.url = queryurl;
		this.merId = merId;
		this.signKey = signKey;
		this.orderNumber = orderNumber;
		this.orderTime = orderTime;
		this.qid = qid;
	}
		
	/**
	 * 订单查询.
	 * <p>
	 * 进行订单查询请求时，商户订单号,交易时间,原始流水号不能全部为空。
	 * <p>
	 */
	public Map<String, String> query() {
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("version", version);
		paramMap.put("charset", charset);
		paramMap.put("signMethod", signMethod);
		paramMap.put("payType", payType);
		paramMap.put("transType", transType);
		paramMap.put("merId", merId);
		paramMap.put("orderNumber", orderNumber);
		paramMap.put("orderTime", orderTime);
		paramMap.put("qid", qid);
		
		// 签名信息
		String[] paramKeys = new String[] { "version", "charset", "signMethod", "payType", "transType", "merId", "orderNumber", "orderTime", "qid" };// 构造签名参数数组
		String sign = PayUtils.signDictionary(paramMap, paramKeys, signKey, charset);// 生成加密签名串
		paramMap.put("sign", sign);
		
		System.out.println("向清算平台发送交易查询请求:" + AppUtils.restMapToStr(paramMap));// 请求报文
		String httpPost = HttpClientUtil.httpPost(url, paramMap, charset);
		System.out.println("清算平台同步响应:" + httpPost);// 返回的响应报文
		
		Map<String, String> map = readStringXml(httpPost, signKey);
		return map;
	}
	
	
	/**
	 * 响应报文解析
	 * 
	 * @param xml
	 * @param puk
	 * @return String
	 */
	
	private Map<String, String> readStringXml(String xml, String signKey) {
		
		Document doc = null;
		String payType = StringUtils.EMPTY;
		String transType = StringUtils.EMPTY;
		String merId = StringUtils.EMPTY;
		String orderNumber = StringUtils.EMPTY;
		String qid = StringUtils.EMPTY;
		String orderAmount = StringUtils.EMPTY;
		String payAmount = StringUtils.EMPTY;
		String state = StringUtils.EMPTY;
		String refundAmount = StringUtils.EMPTY;
		String orderCurrency = StringUtils.EMPTY;
		String orderTime = StringUtils.EMPTY;
		String merReserved1 = StringUtils.EMPTY;
		String merReserved2 = StringUtils.EMPTY;
		String merReserved3 = StringUtils.EMPTY;
		String sign = StringUtils.EMPTY;
		try {
			doc = DocumentHelper.parseText(StringUtils.trim(xml)); // 将字符串转为XML
			Element rootElt = doc.getRootElement(); // 获取根节点
			
			String respCode = rootElt.elementText("respCode");// 返回码
			if (respCode.equals("00")) {
				Iterator<?> iter = rootElt.elementIterator("queryorder"); // 获取根节点下的子节点document
				while (iter.hasNext()) {
					Element itemEle = (Element) iter.next();
					payType = itemEle.elementTextTrim("payType"); // document下的子节点queryorder下的子节点payType的值
					transType = itemEle.elementTextTrim("transType"); // document下的子节点queryorder下的子节点transType的值
					merId = itemEle.elementTextTrim("merId");
					orderNumber = itemEle.elementTextTrim("orderNumber");
					qid = itemEle.elementTextTrim("qid");
					orderAmount = itemEle.elementTextTrim("orderAmount");
					payAmount = itemEle.elementTextTrim("payAmount");
					state = itemEle.elementTextTrim("state");
					refundAmount = itemEle.elementTextTrim("refundAmount");
					orderCurrency = itemEle.elementTextTrim("orderCurrency");
					orderTime = itemEle.elementTextTrim("orderTime");
					merReserved1 = itemEle.elementTextTrim("merReserved1");
					merReserved2 = itemEle.elementTextTrim("merReserved2");
					merReserved3 = itemEle.elementTextTrim("merReserved3");
					sign = itemEle.elementTextTrim("sign");
					
					// 签名验证
					Map<String, String> paramMap = new HashMap<String, String>();
					paramMap.put("payType", payType);
					paramMap.put("transType", transType);
					paramMap.put("merId", merId);
					paramMap.put("orderNumber", orderNumber);
					paramMap.put("qid", qid);
					paramMap.put("orderAmount", orderAmount);
					paramMap.put("payAmount", payAmount);
					paramMap.put("state", state);
					paramMap.put("refundAmount", refundAmount);
					paramMap.put("orderCurrency", orderCurrency);
					paramMap.put("orderTime", orderTime);
					paramMap.put("merReserved1", merReserved1);
					paramMap.put("merReserved2", merReserved2);
					paramMap.put("merReserved3", merReserved3);
					
					String[] paramKeys = new String[] { "payType", "transType", "merId", "orderNumber", "qid", "orderAmount", "payAmount", "state", "refundAmount", "orderCurrency", "orderTime", "merReserved1", "merReserved2",
							"merReserved3", };// 构造签名参数数组
					String calsign = PayUtils.signDictionary(paramMap, paramKeys, signKey, charset);// 生成加密签名串
					
					if (calsign.toUpperCase().equals(sign.toUpperCase())) {
						System.out.println("签名验证成功");
//						AAZ288,  订单号
//						AAE019,  金额
//						AAD017,  缴费日期
//						AAD008, 平台交易流水号
//						AAE354, 成功表示
//						AAE355, 错误信息
//						AAZ295 支付银行类别
						Map<String, String> retMap = new HashMap<String, String>();
						retMap.put("AAC002", paramMap.get("merReserved3")); 
						retMap.put("AAC003", paramMap.get("merReserved1"));
						retMap.put("AAZ288", paramMap.get("orderNumber"));
						retMap.put("AAE019", paramMap.get(""));
						retMap.put("AAD017", paramMap.get("orderTime"));
						retMap.put("AAD008", paramMap.get("qid"));
						retMap.put("AAE354", paramMap.get("state"));
						retMap.put("AAE355", paramMap.get("state"));
						retMap.put("AAZ295", "JH");
						return retMap;
					} else {
						System.out.println("签名验证失败");
					}
				}
			} else if (respCode.equals("03")) {
				System.out.println("无此记录");
			} else if (respCode.equals("04")) {
				System.out.println("数据格式错误");
			} else if (respCode.equals("05")) {
				System.out.println("商户订单号,交易时间,原始流水号不能全部为空");
			} else if (respCode.equals("06")) {
				System.out.println("签名校验未通过");
			}
		} catch (DocumentException e) {
			System.out.println("返回的XML文件解析错误1!" + e.getMessage());
		} catch (Exception e) {
			System.out.println("返回的XML文件解析错误2!" + e.getMessage());
		}
		return null;
	}
	
//	public static void main(String[] args) {
//		JHQuery rs = new JHQuery(PayConf.JSPT_QUERY_URL, PayConf.MERID, PayConf.SIGNKEY,
//				"", "20161027110209", "");
//		Map<String, String> map = rs.query();
//		if(map != null) {
//			for (int i = 0; i < map.keySet().size(); i++) {
//				Iterator<String> s = map.keySet().iterator();
//				System.out.println(map.get(s));
//			}
//		}
//	}
	
	public void downLoad() {
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("version", "2.0");
		paramMap.put("charset", "UTF-8");
		paramMap.put("signMethod", "MD5");
		paramMap.put("transCode", "F001");
		paramMap.put("merId", "10001");
		paramMap.put("billDate", "20161113");
		paramMap.put("billType", "01");
		paramMap.put("fileType", "01");
		paramMap.put("transTime", DateUtil.currentTime());
		paramMap.put("backEndUrl", "http://nobody.vicp.io:10269/recvDownLoadNotify");
		paramMap.put("reqReserved", "");
		// 签名信息
		String[] paramKeys = new String[] { "version", "charset", "signMethod", "transCode", "merId", "billDate", "billType", "fileType", "transTime", "backEndUrl", "reqReserved"};// 构造签名参数数组
		Map<String, String> paraMap = AppUtils.prepareDataMap(paramMap, paramKeys);//数据预处理
		String mac = AppUtils.signBeforePost(paraMap, signKey, charset);
		paraMap.put("sign", mac);
		
		System.out.println("向清算平台发送交易查询请求:" + AppUtils.restMapToStr(paraMap));// 请求报文
		String res = HttpClientUtil.httpPost("http://test.ezf123.com/jspt/download/fileDownloadReq.action", paraMap, charset);
		System.out.println("清算平台同步响应:" + res);// 返回的响应报文
		
		//签名验证
		boolean validate = AppUtils.validate(res, signKey, paraMap.get("charset"));
		if(validate){
			Map<String, String> resMap = new HashMap<String, String>();
			AppUtils.convertRetToMap(res, resMap);
			if("00".equals(resMap.get("respCode"))){
				System.out.println("成功");
			}else{
				System.out.println("失败");
			}
		}else {
			System.out.println("成功");
		}
	}
	
	public static void main(String[] args) {
		JHQuery j = new JHQuery();
		j.downLoad();
	}

}
